iT邦幫忙

2025 iThome 鐵人賽

DAY 15
0
生成式 AI

打造自己的 AI 新聞小編:每天自動抓新聞、摘要、推送到 LINE!系列 第 15

【Day 14】動手寫程式碼!實作訂閱與取消訂閱的邏輯

  • 分享至 

  • xImage
  •  

昨天我們將訂閱主題的內容完成一半了,今天要繼續增加節點!

取消訂閱的節點

If 節點(取消訂閱)的 true 分支新增一個 Code 節點(取消訂閱)。

https://ithelp.ithome.com.tw/upload/images/20250913/20178067WBZKlCMYnf.png

輸入以下程式碼:

const userId = $input.first().json.body.events[0].source.userId;
const staticData = $getWorkflowStaticData('global');
let replyMessage;

// 檢查 subscriptions 內容是否存在,如果不存在就回覆沒有訂閱
if (!staticData.subscriptions) {
    replyMessage = '您沒有訂閱任何新聞。';
} else {
    // 取得使用者當前的訂閱主題
    const topic = staticData.subscriptions[userId];
    if (topic) {
        // 刪除訂閱
        delete staticData.subscriptions[userId];
        replyMessage = `已成功取消訂閱${topic}新聞!`;
    } else {
        replyMessage = '您沒有訂閱任何新聞。';
    }
}
return [{
    json: {
        replyToken: $input.first().json.body.events[0].replyToken,
        messages: [{
            type: "text",
            text: replyMessage
        }]
    }
}];

程式碼有點長,但不要覺得很難,這段內容其實滿好懂的,我們拆成三個部分來看吧~

第一部分:讀取資料

前兩行是用來提取使用者的 ID,用來識別是哪一個 LINE 使用者傳送訊息、讀取你儲存在 n8n 靜態資料庫中的所有資料。

第二部分:核心邏輯

這部分是判斷使用者是否有訂閱,並根據情況產生不同的回覆訊息。

if (!staticData.subscriptions):這行程式碼會先檢查靜態資料中,有沒有一個叫做 subscriptions 的物件。

  • 如果沒有,表示這是這個 LINE Bot 第一次被使用,或者資料被清空了,它會將 replyMessage 設定為 '您沒有訂閱任何新聞。'
  • 如果,程式碼會進入 else 區塊。

const topic = staticData.subscriptions[userId]:這行程式碼會試著從 subscriptions 物件中,用 userId 當作鑰匙,取出使用者先前訂閱的主題。

if (topic):這行程式碼會檢查 topic 這個變數有沒有值。

  • 如果,表示這個使用者有訂閱,程式碼會執行 delete staticData.subscriptions[userId];刪除這個使用者的訂閱資料,然後將 replyMessage 設定為 '已成功取消訂閱${topic}新聞!'
  • 如果沒有,表示這個使用者沒有訂閱任何主題,它會將 replyMessage 設定為 '您沒有訂閱任何新聞。'

第三部分:回傳

雖然上面的程式碼已經寫了要傳給使用者的訊息,但你沒辦法只用這個節點就讓使用者收到訊息,還需要用 HTTP Request 節點才能真的傳送訊息給使用者,所以我們要將處理好的資料傳給下一個節點。
LINE 會用 replyToken 來確認回覆的對象,所以即使只有一個使用者,每次對話也都需要一個不同的 replyToken
replyToken 的主要目的並不是區分不同使用者,而是用來標記每一次的獨立對話

這樣看完是不是覺得這個節點的程式碼很清楚了,接下來我們要新增一個節點來處理「訂閱」的訊息,跟這個節點的概念差不多!

儲存訂閱的節點

If 節點(訂閱)的 true 分支新增一個 Code 節點(訂閱)。

https://ithelp.ithome.com.tw/upload/images/20250913/20178067vq4adzqvRw.png

這個節點的程式碼我就不詳細說明了,和剛剛的程式碼概念差不多,程式碼註解應該就很清楚了~

輸入以下程式碼:

const messageText = $input.first().json.body.events[0].message.text;
const userId = $input.first().json.body.events[0].source.userId;

// 從訊息中提取主題
const topic = messageText.replace('訂閱', '').trim();
const staticData = $getWorkflowStaticData('global');

// 檢查 subscriptions 物件是否存在,如果不存在就建立它
if (!staticData.subscriptions) {
    staticData.subscriptions = {};
}

// 儲存使用者的訂閱主題
staticData.subscriptions[userId] = topic;

// 回傳
return [{
    json: {
        replyToken: $input.first().json.body.events[0].replyToken,
        messages: [{
            type: "text",
            text: `已成功訂閱${topic}新聞!`
        }]
    }
}];

這段程式碼和剛剛的差別有兩點:

  1. const messageText = $input.first().json.body.events[0].message.text;
    「取消訂閱」的程式碼沒有這句,因為它要做的不是去讀取訊息內容,而是直接去尋找使用者 ID,然後將這個 ID 從靜態資料庫中刪除
    所以,它只需要知道是「」傳了訊息,而不需要知道訊息的「內容」。

    還記得嗎?我們設定使用者只能訂閱一個主題!

  2. const topic = messageText.replace('訂閱', '').trim();
    只有訂閱的主題才需要被記錄。

因為今天的程式碼很長,內容有點多,雖然只做了兩個節點但也花費了不少時間,所以將其他節點放到接下來幾篇文章中,一步一步跟著我完成這個功能的建立吧!

下篇預告

明天(Day 15)會示範如何在使用者取消訂閱時,自動恢復預設主題新聞。


上一篇
【Day13】讓 Webhook 正式上線,並實作訂閱功能骨架
下一篇
【Day 15】新增取消訂閱邏輯:自動恢復預設 & 即時回覆訊息
系列文
打造自己的 AI 新聞小編:每天自動抓新聞、摘要、推送到 LINE!21
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言